package com.tianjin.weight.model.pc;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.PageHelper;
import com.tianjin.weight.constants.Constant;
import com.tianjin.weight.entity.Ao;
import com.tianjin.weight.entity.Page;
import com.tianjin.weight.entity.SysPermission;
import com.tianjin.weight.exception.BusinessException;
import com.tianjin.weight.exception.code.BaseResponseCode;
import com.tianjin.weight.model.common.Permission;
import com.tianjin.weight.service.RedisService;
import com.tianjin.weight.utils.MapperBeanUtils;
import com.tianjin.weight.utils.PageUtils;
import com.tianjin.weight.utils.TokenSettings;
import com.tianjin.weight.vo.resp.PageVO;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


public  class PermissionWithPing<T extends SysPermission,F extends Page>  extends Permission<T,F> {
    @Autowired
    private RedisService redisService;

    @Autowired
    private TokenSettings tokenSettings;

    public PermissionWithPing(T vo, F fo, Ao ao) {
        super(vo, fo, ao);
    }


    @Override
    public void addPermissionAfter() throws Exception {

    }

    @Override
    public void updatePermissionBefore() throws Exception {
        SysPermission oriSysPermission = MapperBeanUtils.getSysPermissionMapper().selectByPrimaryKey(ao.id);
        if (null==oriSysPermission){
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        SysPermission sysPermission = SysPermission.builder()
                .id(ao.id)
                .name(vo.getName())
                .perms(vo.getPerms())
                .url(vo.getUrl())
                .method(vo.getMethod())
                .pid(vo.getPid())
                .orderNum(vo.getOrderNum())
                .type(vo.getType())
                .status(vo.getStatus())
                .build();
        if(oriSysPermission.getType()!=vo.getType()||!oriSysPermission.getPid().equals(vo.getPid())){
//            verifyForm(sysPermission);
        }
        sysPermission.setUpdateTime(new Date());
        MapperBeanUtils.getSysPermissionMapper().updateByPrimaryKeySelective(sysPermission);
        ao.subject = sysPermission;
    }

    @Override
    public void updatePermissionAfter() throws Exception {
        SysPermission sysPermission  = (SysPermission) ao.subject;
        /**
         * 说明这个菜单权限 权鉴标识发生变化
         * 所有管理这个菜单权限用户将重新刷新token
         */
        if(StringUtils.isEmpty(vo.getPerms())&&!sysPermission.getPerms().equals(vo.getPerms())){
            List<Long> roleIds = MapperBeanUtils.getSysRolePermissionMapper().getRoleIds(vo.getId());
            if(!roleIds.isEmpty()){
                List<Long> userIds = MapperBeanUtils.getSysUserRoleMapper().getUserIdsByRoleIds(roleIds);
                if(!userIds.isEmpty()){
                    for (Long userId:userIds){
                        redisService.set(Constant.JWT_REFRESH_KEY +userId,userId,tokenSettings.getAccessTokenExpireTime().toMillis(), TimeUnit.MILLISECONDS);
                        //清空权鉴缓存
                        redisService.delete(Constant.IDENTIFY_CACHE_KEY+userId);
                    }

                }
            }
        }
    }

    @Override
    public void deletePermissionBefore() throws Exception {
        SysPermission sysPermission = MapperBeanUtils.getSysPermissionMapper().selectByPrimaryKey(ao.id);
        if(null==sysPermission){
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        List<SysPermission> childs = MapperBeanUtils.getSysPermissionMapper().selectChild(ao.id);
        if(!childs.isEmpty()){
            throw new BusinessException(BaseResponseCode.ROLE_PERMISSION_RELATION);
        }
        MapperBeanUtils.getSysPermissionMapper().deleteByPrimaryKey(ao.id);
    }

    @Override
    public void deletePermissionAfter() throws Exception {
        /**
         * 删除和角色关联
         */
        MapperBeanUtils.getSysRolePermissionMapper().removeByPermissionId(ao.id);
        List<Long> roleIds =MapperBeanUtils.getSysRolePermissionMapper().getRoleIds(ao.id);
        if(!roleIds.isEmpty()){
            List<Long> userIds = MapperBeanUtils.getSysUserRoleMapper().getUserIdsByRoleIds(roleIds);
            if(!userIds.isEmpty()){
                for (Long userId:userIds){
                    redisService.set(Constant.JWT_REFRESH_KEY +userId,userId,tokenSettings.getAccessTokenExpireTime().toMillis(), TimeUnit.MILLISECONDS);
                    //清空权鉴缓存
                    redisService.delete(Constant.IDENTIFY_CACHE_KEY+userId);
                }

            }
        }
    }


    @Override
    public void batchDelete() throws Exception {

    }

    @Override
    public T getOne() throws Exception {
        return (T) MapperBeanUtils.getSysPermissionMapper().selectByPrimaryKey(ao.id);
    }

    @Override
    public T getSearchOne() throws Exception {
        return null;
    }

    @Override
    public List<T> getAll() throws Exception {
        List<T> result = (List<T>) MapperBeanUtils.getSysPermissionMapper().selectAll();
        if(!result.isEmpty()){
            for (T sysPermission:result){
                T parent= (T) MapperBeanUtils.getSysPermissionMapper().selectByPrimaryKey(sysPermission.getPid());
                if (parent!=null){
                    sysPermission.setPidName(parent.getName());
                }
            }
        }
        return result;
    }

    @Override
    public List<T> getSearchAll() throws Exception {
        return null;
    }

    @Override
    public PageVO<T> getList() throws Exception {
        PageHelper.startPage(fo.getPageNum(),fo.getPageSize());
        List<T> result = (List<T>) MapperBeanUtils.getSysPermissionMapper().selectAll();
        if(!result.isEmpty()){
            for (T sysPermission:result){
                T parent= (T) MapperBeanUtils.getSysPermissionMapper().selectByPrimaryKey(sysPermission.getPid());
                if (parent!=null){
                    sysPermission.setPidName(parent.getName());
                }
            }
        }
        return PageUtils.getPageVO(result);
    }

    @Override
    public PageVO<T> getSearchList() throws Exception {
        return null;
    }



}
